﻿using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using log4net;
using Mathmall.Administration.common;
using Mathmall.Administration.Config;
using Mathmall.Administration.Helper;
using Mathmall.Administration.Mapper;
using Mathmall.Administration.Models;
using Mathmall.Administration.Vo;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using UserOptions = Mathmall.Administration.Config.UserOptions;

namespace Mathmall.Administration.Service.impl
{
    public class UserService : IUserService
    {
        private static readonly ILog _logger = LogManager.GetLogger(typeof(UserService));
        private readonly UserManager<User> _userManager;
        private readonly UserMapper _userMapper;
        private readonly UserOptions _userOptions;
        private readonly JwtHelper _jWTHelper;

        public UserService(UserMapper userMapper, IOptionsSnapshot<UserOptions> userOptions,
            UserManager<User> userManager, JwtHelper jWTHelper)

        {
            _userMapper = userMapper;
            _userOptions = userOptions.Value;
            _userManager = userManager;
            _jWTHelper = jWTHelper;
        }

        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="userVo">用户信息</param>
        /// <returns></returns>
        public async Task<IdentityResult> AddUser(UserVo userVo)
        {
            User user = new User()
            {
                EmailConfirmed = _userOptions.EmailConfirmed,
                PhoneNumberConfirmed = _userOptions.PhoneNumberConfirmed,
                TwoFactorEnabled = _userOptions.TwoFactorEnabled,
                LockoutEnabled = _userOptions.LockoutEnabled,
            };

            user.Avatar = userVo.Avatar;
            user.PasswordHash = userVo.Password;
            user.UserName = userVo.Username;
            return await _userMapper.AddUser(user);
        }

        /// <summary>
        /// 分页查询用户信息
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<PaginatedList<UserVo>> PaginatedQuery(int pageIndex, int pageSize, string condition)
        {
            // 查询符合条件的全部数据
            IQueryable<User> users = _userMapper.GetAllUsers()
                .Where(user => user.UserName != null && user.UserName.Contains(condition));

            // 进行分页
            PaginatedList<User> usersPaginatedList = await PaginatedList<User>.CreateAsync(users, pageIndex, pageSize);
            // 将查到的数据序列化为vo
            List<UserVo> userVos = new List<UserVo>();
            foreach (User user in usersPaginatedList.Items)
            {
                UserVo userVo = JsonSerializer.Deserialize<UserVo>(JsonSerializer.Serialize(user))!;
                userVo.Username = user.UserName;
                userVo.UserId = user.Id;
                // 查询用户角色
                IList<string> roles = await _userManager.GetRolesAsync(user);
                foreach (string role in roles)
                {
                    userVo.Roles?.Add(role);
                }

                userVos.Add(userVo);
            }

            return new PaginatedList<UserVo>(userVos, usersPaginatedList.Count, pageIndex, pageSize);
        }

        /// <summary>
        /// 给用户添加角色
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="roleNames"></param>
        /// <returns></returns>
        public async Task<IdentityResult> DistributeRole(int userId, List<string> roleNames)
        {
            // 根据id查找用户
            User user = await _userMapper.GetUserById(userId);
            // 删除用户的角色信息
            List<int> ids =
            [
                userId
            ];
            await _userMapper.DeleteUserRole(ids);
            // 重新添加角色
            return await _userManager.AddToRolesAsync(user, roleNames);
        }

        /// <summary>
        /// 根据用户id集合批量删除用户
        /// </summary>
        /// <param name="userIds"></param>
        /// <returns></returns>
        public async Task<int> DeleteUsersByUserIds(List<int> userIds)
        {
            return await _userMapper.DeleteUsersByUserIds(userIds);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginVo"></param>
        /// <returns></returns>
        public async Task<UserVo?> UserLogin(LoginVo loginVo)
        {
            // 查询用户
            var user = await _userMapper.Select(loginVo.Username, loginVo.Password);

            if (user is not null)
            {
                // 查询用户角色id
                List<int> roleIds = await _userMapper.GetRoleIdsByUserId(user.Id);
                // 查询用户菜单
                List<string> menuNames = new List<string>();
                List<string> buttons = new List<string>();
                List<Menu> menus = await _userMapper.GetMenusByRoleId(roleIds);
                foreach (Menu menu in menus)
                {
                    menuNames.Add(menu.MenuName!);
                    buttons.Add(menu.AuthorityValue!);
                }

                // 生成jwt
                string token = _jWTHelper.CreateToken(user, roleIds);
                UserVo userVo = JsonSerializer.Deserialize<UserVo>(JsonSerializer.Serialize(user))!;
                userVo.Token = token;
                userVo.Username = user.UserName;
                userVo.Password = "";
                userVo.Permissions = menuNames;
                userVo.Buttons = buttons;

                return userVo;
            }

            return null;
        }
    }
}